home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Reference Guide
/
C-C++ Interactive Reference Guide.iso
/
c_ref
/
csource5
/
311_01
/
db_dict.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-04-23
|
10KB
|
503 lines
/****************************************************************************/
/* */
/* */
/* db_dict.c - dictionary (symtable manager) routines */
/* v1.3 (c) 1990 Ken Harris */
/* */
/* */
/****************************************************************************/
/* */
/* This software is made available on an AS-IS basis. Unrestricted */
/* use is granted provided that the copyright notice remains intact. */
/* The author makes no warranties expressed or implied. */
/* */
/****************************************************************************/
#include "dblib.h"
#ifdef ANSI
static void strupr(char *);
#else
static void strupr();
#endif
char *calloc();
/*
* db_dict_hash - Computer hash value for a name
*/
static db_dict_hash(name)
char *name;
{
long x=0;
while (*name) x += *name++;
return(x % DICT_HASH_SIZE);
}
/*
* db_dict_init - Initialize a Dictionary
*/
DICT db_dict_init()
{ DICT dict;
int i;
db_error = 0;
dict = (DICT) calloc(sizeof(struct db_dict_hdr), 1);
if (!dict)
{ db_error = DB_ALLOC_ERROR;
return(NULL);
}
dict->magic = DICT_MAGIC;
for (i=0; i<DICT_HASH_SIZE; i++)
dict->htbl[i] = NULL;
return(dict);
}
/*
* db_dict_add - add a new object to the dictionary
*/
void *db_dict_add(dict, name, o_type, d_size, data)
DICT dict;
char *name;
int o_type;
int d_size;
void *data;
{
short hval, o_size;
DOBJ dobj;
char *o_name, *o_data;
db_error = 0;
if (!dict || dict->magic != DICT_MAGIC)
{ db_error = DB_INVALID_DICT;
return(NULL);
}
if (!name || !*name)
{ db_error = DB_INVALID_NAME;
return(NULL);
}
strupr(name);
hval = db_dict_hash(name);
if (db_dict_find(dict, name, o_type))
{ db_dict_delete(dict, name, o_type);
if (db_error) return(NULL);
}
else
db_error = 0;
o_size = sizeof(struct db_dict_obj) + strlen(name) + d_size;
dobj = (DOBJ) calloc(o_size, 1);
if (!dobj)
{ db_error = DB_ALLOC_ERROR;
return(NULL);
}
dobj->o_type = o_type;
dobj->next = dict->htbl[hval];
dict->htbl[hval] = dobj;
dobj->n_size = strlen(name);
dobj->d_size = d_size;
o_data = &dobj->data;
o_name = o_data + dobj->d_size;
strcpy(o_name, name);
if (data) memcpy(o_data, data, d_size);
return(o_data);
}
/*
* db_dict_delete - delete an object by name
*/
void db_dict_delete(dict, name, o_type)
DICT dict;
char *name;
int o_type;
{
DOBJ prev, cur, next;
short hval;
char *cur_name;
db_error = 0;
if (!dict || dict->magic != DICT_MAGIC)
{ db_error = DB_INVALID_DICT;
return;
}
if (!name || !*name)
{ db_error = DB_INVALID_NAME;
return;
}
strupr(name);
hval = db_dict_hash(name);
prev = NULL;
cur = dict->htbl[hval];
while (cur)
{ cur_name = &cur->data + cur->d_size;
if (strcmp(cur_name, name)==0 &&
(cur->o_type==o_type || o_type==0))
{ if (prev)
prev->next = cur->next;
else
dict->htbl[hval] = cur->next;
next = cur->next;
free(cur);
cur = next;
}
else
{ prev = cur;
cur = cur->next;
}
}
}
/*
* db_dict_delete_all - delete all objects of a type
*/
void db_dict_delete_all(dict, o_type)
DICT dict;
int o_type;
{
DOBJ prev, cur, next;
short hval, i;
db_error = 0;
if (!dict || dict->magic != DICT_MAGIC)
{ db_error = DB_INVALID_DICT;
return;
}
for (i=0; i<DICT_HASH_SIZE; i++)
{ prev = NULL;
cur = dict->htbl[i];
while (cur)
{ if (cur->o_type==o_type || o_type==0)
{ if (prev)
prev->next = cur->next;
else
dict->htbl[i] = cur->next;
next = cur->next;
free(cur);
cur = next;
}
else
{ prev = cur;
cur = cur->next;
}
}
}
}
/*
* db_dict_find - Find a object by name
*/
void *db_dict_find(dict, name, o_type)
DICT dict;
char *name;
int o_type;
{
DOBJ dobj;
short hval;
char *o_name;
db_error = 0;
if (!dict || dict->magic != DICT_MAGIC)
{ db_error = DB_INVALID_DICT;
return(NULL);
}
if (!name || !*name)
{ db_error = DB_INVALID_NAME;
return(NULL);
}
strupr(name);
hval = db_dict_hash(name);
dobj = dict->htbl[hval];
while (dobj)
{ o_name = &dobj->data + dobj->d_size;
if (strcmp(o_name,name)==0 &&
(dobj->o_type==o_type || o_type==0))
return(&dobj->data);
dobj = dobj->next;
}
db_error = DB_REC_NOT_FOUND;
return(NULL);
}
/*
* db_dict_find_all - Find all objects by type
*/
db_dict_find_all(dict, o_type, nlist, dlist)
DICT dict;
int o_type;
char **nlist[];
void **dlist[];
{
DOBJ dobj;
short i, j, cnt;
char *tmp, *o_name, *o_data;
db_error = 0;
if (!dict || dict->magic != DICT_MAGIC)
{ db_error = DB_INVALID_DICT;
return(0);
}
for (i=0, cnt=0; i<DICT_HASH_SIZE; i++)
{ dobj = dict->htbl[i];
while (dobj)
{ if (dobj->o_type==o_type || o_type==0) cnt++;
dobj = dobj->next;
}
}
if (!cnt)
{ db_error = DB_REC_NOT_FOUND;
*nlist = NULL;
*dlist = NULL;
return(0);
}
*nlist = (char **) calloc(sizeof(char *), cnt);
if (!*nlist)
{ db_error = DB_ALLOC_ERROR;
return(0);
}
*dlist = (void **) calloc(sizeof(char *), cnt);
if (!*dlist)
{ db_error = DB_ALLOC_ERROR;
free(*nlist);
return(0);
}
for (i=0, cnt=0; i<DICT_HASH_SIZE; i++)
{ dobj = dict->htbl[i];
while (dobj)
{ if (dobj->o_type==o_type || o_type==0)
{ o_data = &dobj->data;
o_name = o_data + dobj->d_size;
(*nlist)[cnt] = o_name;
(*dlist)[cnt] = o_data;
cnt++;
for (j=cnt-1; j>0; j--)
{ if (strcmp((*nlist)[j],(*nlist)[j-1])<0)
{ tmp = (*nlist)[j];
(*nlist)[j] = (*nlist)[j-1];
(*nlist)[j-1] = tmp;
tmp = (*dlist)[j];
(*dlist)[j] = (*dlist)[j-1];
(*dlist)[j-1] = tmp;
}
else
break;
}
}
dobj = dobj->next;
}
}
return(cnt);
}
/*
* db_dict_load - Load dictionary entries from a file
*/
void db_dict_load(dict, path, fname)
DICT dict;
char *path, *fname;
{
DATA_FILE df;
FILE_HDR fh;
DOBJ dobj;
char *o_name, *buf;
unsigned o_size, hval;
db_error = 0;
if (!dict || dict->magic != DICT_MAGIC)
{ db_error = DB_INVALID_DICT;
return;
}
if (!fname || !*fname)
{ db_error = DB_INVALID_NAME;
return;
}
df = db_open(path, fname);
if (db_error) return;
fh = (FILE_HDR)df->df_fhdr;
buf = (char *)calloc(fh->fh_rec_size, 1);
if (!buf)
{ db_error = DB_ALLOC_ERROR;
return;
}
db_read_first(df, buf, &o_size);
while (!db_error)
{ dobj = (DOBJ) calloc(o_size, 1);
if (!dobj)
{ db_error = DB_ALLOC_ERROR;
free(buf);
return;
}
memcpy(dobj, buf, o_size);
o_name = &dobj->data + dobj->d_size;
hval = db_dict_hash(o_name);
dobj->next = dict->htbl[hval];
dict->htbl[hval] = dobj;
db_read_next(df, buf, &o_size);
}
if (db_error = DB_END_OF_FILE) db_error = 0;
free(buf);
db_close(df);
}
/*
* db_dict_dump - Dump dictionary objects to a file
*/
void db_dict_dump(dict, path, fname)
DICT dict;
char *path, *fname;
{
DATA_FILE df;
DOBJ dobj;
unsigned o_size, i, cnt, max_size;
char options[50];
db_error = 0;
if (!dict || dict->magic != DICT_MAGIC)
{ db_error = DB_INVALID_DICT;
return;
}
if (!fname || !*fname)
{ db_error = DB_INVALID_NAME;
return;
}
for (i=0, cnt=0, max_size=0; i<DICT_HASH_SIZE; i++)
{ dobj = dict->htbl[i];
while (dobj)
{ o_size = sizeof(struct db_dict_obj) + dobj->d_size
+ dobj->n_size;
if (o_size > max_size) max_size = o_size;
cnt++;
dobj = dobj->next;
}
}
if (!cnt)
{ db_error = DB_REC_NOT_FOUND;
return;
}
sprintf(options,"VAR, REC=%d", max_size);
df = db_create(path, fname, options);
if (db_error) return;
for (i=0; i<DICT_HASH_SIZE; i++)
{ dobj = dict->htbl[i];
while (dobj)
{ o_size = sizeof(struct db_dict_obj) + dobj->d_size
+ dobj->n_size;
db_add(df, dobj, o_size);
if (db_error) return;
dobj = dobj->next;
}
}
db_close(df);
}
/*
* db_dict_close - Close a dictionary and dispose of its contents
*/
void db_dict_close(dict)
DICT dict;
{
DOBJ dobj, next;
short i;
db_error = 0;
if (!dict || dict->magic != DICT_MAGIC)
{ db_error = DB_INVALID_DICT;
return;
}
for (i=0; i<DICT_HASH_SIZE; i++)
{ dobj = dict->htbl[i];
while (dobj)
{ next = dobj->next;
free(dobj);
dobj = next;
}
}
dict->magic = 0;
free(dict);
}
/*
* strupr - convert string to upper case
*/
static void strupr(str)
char *str;
{
while (*str)
{ if (islower(*str)) *str = toupper(*str);
str++;
}
}